#ifndef LOGIN_CLIENT_IMP_H
#define LOGIN_CLIENT_IMP_H

#include "i_package.h"
#include "arc4_codec.h"
#include "login_client.h"
#include "challenge_package.h"
#include "challenge_response.h"
#include "keyexchange_package.h"
#include "keyexchange_response.h"

#include <osrng.h>
#include <hmac.h>
#include <sha.h>

using namespace CryptoPP;

namespace login_client_detail
{
	class ChallengePhase;
	class State;

	class Imp
	{
	public:
		const string userName_;
		const string password_;
		byte digestOfUserPassword_[SHA::DIGESTSIZE];

		boost::shared_ptr<State> currentState_;

		LoginAuthDelegate loginFailed_;
		LoginAuthDelegate loginSuccessed_;

		Imp(const string& userName, const string& password);

		void handle(IPackage* package, IIoHandler::Ptr ioHandler);

		inline void setLoginFailedDelegate(LoginAuthDelegate loginFailed)
		{
			loginFailed_ = loginFailed;
		}

		inline void setLoginSuccessDelegate(LoginAuthDelegate loginSuccessed)
		{
			loginSuccessed_ = loginSuccessed;
		}
	};


	class State
	{
	public:
		virtual bool handle(IPackage* package, Imp* loginClient, IIoHandler::Ptr ioHandler) = 0;
	};


	class ChallengePhase : public State
	{
	public:
		virtual bool handle(IPackage* package, Imp* loginClient, IIoHandler::Ptr ioHandler);
	};


	class KeyExchangePhase : public State
	{
	public:
		virtual bool handle(IPackage* package, Imp* loginClient, IIoHandler::Ptr ioHandler);
	};
}
#endif